/*
Package response
@Author   : Uyynot
@Email    : uyynot@qq.com
@Time     : 2024/2/21 16:29
@File     : response.go
@Project  : gohub
@Desc     :
*/
package response

import (
	"github.com/gin-gonic/gin"
	"gohub/pkg/logger"
	"gorm.io/gorm"
	"net/http"
)

// JSON 响应200和json数据
func JSON(c *gin.Context, data any) {
	c.JSON(http.StatusOK, data)
}

// Success 响应 200 和预设『操作成功！』的 JSON 数据
// 执行某个『没有具体返回数据』的『变更』操作成功后调用，例如删除、局部修改
func Success(c *gin.Context) {
	JSON(c, gin.H{
		"success": true,
		"message": "操作成功",
	})
}

// Data 响应 200 和带 data 键的 JSON 数据
// 执行『更新操作』成功后调用，例如更新记录，成功后返回已更新的记录
func Data(c *gin.Context, data any) {
	JSON(c, gin.H{
		"success": true,
		"data":    data,
	})
}

// Created 响应 201 和带 data 键的 JSON 数据
// 执行『创建操作』成功后调用，例如创建记录，成功后返回已创建的记录
func Created(c *gin.Context, data any) {
	c.JSON(http.StatusCreated, gin.H{
		"success": true,
		"data":    data,
	})
}

// CreatedJSON 响应 201 和 JSON 数据
func CreatedJSON(c *gin.Context, data any) {
	c.JSON(http.StatusCreated, data)
}

// Abort404 响应404，未传参时使用默认参数
func Abort404(c *gin.Context, args ...string) {
	c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
		"message": defaultArgs("not found", args...),
	})
}

// Abort403 响应403，未传参是用默认参数
func Abort403(c *gin.Context, args ...string) {
	c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
		"message": defaultArgs("权限不足", args...),
	})
}

// Abort500 响应500，未传参是用默认参数
func Abort500(c *gin.Context, args ...string) {
	c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
		"message": defaultArgs("服务器内部错误", args...),
	})
}

// BadRequest 响应400， 传参err对象，未传参使用默认参数
// 解析用户请求时，请求的格式或者方法不符合预期时调用
func BadRequest(c *gin.Context, err error, args ...string) {
	logger.LogIf(err)
	c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
		"message": defaultArgs("请求解析错误", args...),
		"error":   err.Error(),
	})
}

// Error 响应 404 或 422，未传参 msg 时使用默认消息
// 处理请求时出现错误 err，会附带返回 error 信息，如登录错误、找不到 ID 对应的 Model
func Error(c *gin.Context, err error, args ...string) {
	logger.LogIf(err)
	//类型为 数据库未找到内容
	if err == gorm.ErrRecordNotFound {
		Abort404(c)
		return
	}

	c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{
		"message": defaultArgs("请求处理失败", args...),
		"error":   err.Error(),
	})
}

// ValidationError 处理表单验证不通过的错误，返回的 JSON 示例：
//         {
//             "errors": {
//                 "phone": [
//                     "手机号为必填项，参数名称 phone",
//                     "手机号长度必须为 11 位的数字"
//                 ]
//             },
//             "message": "请求验证不通过，具体请查看 errors"
//         }

func ValidationError(c *gin.Context, errors map[string][]string) {
	c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{
		"message": "请求验证不通过",
		"errors":  errors,
	})
}

// Unauthorized 响应 401，未传参 msg 时使用默认消息
// 登录失败、jwt 解析失败时调用
func Unauthorized(c *gin.Context, msg ...string) {
	c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
		"message": defaultArgs("请求解析错误，请确认请求格式是否正确。上传文件请使用 multipart 标头，参数请使用 JSON 格式。", msg...),
	})
}

// 辅助函数，用以支持默认参数默认值
// go不支持参数默认值，只能使用多变参数来实现类似效果
func defaultArgs(defaultArg string, args ...string) string {
	if len(args) > 0 {
		return args[0]
	}
	return defaultArg
}
